"""

Computational Economics
05: Loops
http://johnstachurski.net/lectures/loops.html

"""


import math, random


"""
    Problem 1:

        * Compute n! using a while loop
              o Get n from the user
"""
prompt = 'Input a number and we will factorialize it: '
n = int(raw_input(prompt))
n_in = n
n_fact = 1

while n:
    n_fact *= n
    n -= 1

print '%s! = %s' % (n_in, n_fact)



"""
    Problem 2:

        * Get numbers from user and print average
              o Keep prompting for a new number
              o Stop when user presses Enter (without number)
"""
user_input = 'start'
inputs = []
prompt = 'Input a number for current average of all inputs. (Hit enter to stop): '

while user_input != '':
    user_input = raw_input(prompt)
    if not user_input:
        break
    inputs.append(float(user_input))
    print 'average for %s: %.2f' % (inputs, sum(inputs) / len(inputs))


"""
        Problem 3:

        * A Monte Carlo study of random walks
              o X starts at zero and increments by 1 or -1 with 0.5 prob
              o Runs until either X = A or X = -B, where A, B > 0
              o The probability of the first case (i.e., X = A) is known to be B / (A + B)
              o Verify this using Monte Carlo
                    + Pick any values for A and B (e.g., A, B = 2, 12)
                    + Draw a large number of such time series
                    + What fraction of these series hit A first?
"""
A, B = random.randint(1,12), random.randint(1,12)

# start walking
def do_random_walk():
    global A, B
    X = 0
    while X != A and X != -B:
        X += (random.uniform(0, 1) > 0.5) and 1 or -1
        if X == A:
            return 'A'
        elif X == -B:
            return 'B'

# run trials
n = 10000
results = []

for i in range(n):
    results.append(do_random_walk())

expected_result = float(B) / (A + B)
actual_result = sum([r == 'A' for r in results]) / float(n)
percent_error = (abs(actual_result - expected_result) / expected_result) * 100

print """
    Random Walk Results:

    trials: %s
    A, B: %s, %s
    expected result: %.2f
    actual result: %.2f
    error: %.2f%%
""" % (n, A, B, expected_result, actual_result, percent_error)



print '%s: ok' % (__file__)

